// Main header
#include "../Main.h"

// My header
#include "Controller_Main.h"

// Fridge
#include "Controller_ModalDialog.h"
#include "Controller_ModalColourPickerDialog.h"
#include "Controller_ModalAddWidgetDialog.h"
#include "Controller_Screen_Editor.h"
#include "Controller_Screen_Main.h"
#include "../Input.h"
#include "../FileTools.h"
#include "../TextureManager.h"
#include "../Preset/Preset.h"
#include "../Widgets/Panel.h"
#include "../Widgets/DragDrop.h"

static const u_int uBACK_COLOUR = 0xFFFFFFFF;

static const char* const szTEXTURE_LIST_FILE = "Graphics/TextureList.dat";


TextureManager*		Controller_Main::s_pxTextureManager = 0;
SDL_Window*			Controller_Main::s_pxWindow			= 0;
SDL_GLContext		Controller_Main::s_xContext			= 0;
CONTROLLER_SCREEN	Controller_Main::s_eScreen			= CONTROLLER_SCREEN_NONE;
Panel*				Controller_Main::s_pxWindowPanel	= NULL;
bool				Controller_Main::s_bShouldQuit		= false;
Input*				Controller_Main::s_pxInputHandler	= NULL;
u_int				Controller_Main::s_uHeight		    = MIN_SCREEN_HEIGHT;
u_int				Controller_Main::s_uWidth		    = MIN_SCREEN_WIDTH;
Preset*				Controller_Main::s_pxPreset			= 0;
TypedStack< Widget > Controller_Main::s_xModalStack;

void Controller_Main::Initialise ( Preset* pxPreset, const CONTROLLER_SCREEN eScreen )
{
	FridgeLog("Controller init\n");

    // Clean start!
    FileTools::RemoveTempDirectory();

	s_pxWindow = SDL_CreateWindow( "Fridge Controller", 50, 100, s_uWidth, s_uHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE );
	s_xContext = SDL_GL_CreateContext( s_pxWindow );
	SDL_GL_MakeCurrent( s_pxWindow, s_xContext );
	s_pxPreset = pxPreset;
    s_pxPreset->CreateWorkingFiles();

	DragDropManager::Initialise();

	s_pxInputHandler = new Input();

	s_pxWindowPanel = new Panel( NULL );
	s_pxWindowPanel->SetPosition( 0, 0 );
	s_pxWindowPanel->SetSize( s_uWidth, s_uHeight );
	s_pxWindowPanel->SetColour( uBACK_COLOUR );
	s_pxWindowPanel->SetAnchors( ANCHORS_ALL );
	
	s_pxTextureManager = new TextureManager();
	s_pxTextureManager->LoadFromTextureListFile( szTEXTURE_LIST_FILE );
	
	Controller_ModalDialog::Initialise();
	Controller_ModalAddWidgetDialog::Initialise();
	Controller_ModalColourPickerDialog::Initialise();
	
	if( eScreen != CONTROLLER_SCREEN_NONE )
	{
		ChangeScreen( eScreen );
	}
}


void Controller_Main::Update ( )
{
	switch( s_eScreen )
	{
		case CONTROLLER_SCREEN_NONE:
		{
			ChangeScreen( CONTROLLER_SCREEN_MAIN );
		}
		break;

		case CONTROLLER_SCREEN_EDITOR:
		{
			if( s_pxPreset )
			{
				s_pxPreset->Update();
			}
			Controller_Screen_Editor::Update();
		}
		break;
	}

	DragDropManager::Update();

	// If we have modal widgets just update the top of the modal stack
	if( s_xModalStack.Count() > 0 )
	{
		Widget* pxModal = s_xModalStack.GetTop();
		if( pxModal )
		{
			pxModal->Update();
		}
	}
	else
	{
		s_pxWindowPanel->Update();
	}

	Controller_ModalDialog::Update();
	Controller_ModalColourPickerDialog::Update();
	Controller_ModalAddWidgetDialog::Update();

	s_pxInputHandler->SwapInputBuffers();
}


void Controller_Main::Render( )
{
	SDL_GL_MakeCurrent( s_pxWindow, s_xContext );

	glViewport( 0, 0, s_uWidth, s_uHeight );

	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	glOrtho( 0, s_uWidth, s_uHeight, 0, -1, 1 );
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
	glEnable( GL_TEXTURE_2D );
	glEnable( GL_BLEND );

	s_pxWindowPanel->Render();

	DragDropManager::Render();

	glFinish();

	SDL_GL_SwapWindow( s_pxWindow );
}


void Controller_Main::Shutdown ( )
{
	Controller_ModalDialog::Shutdown();
	Controller_ModalAddWidgetDialog::Shutdown();
	Controller_ModalColourPickerDialog::Shutdown();

	DragDropManager::Shutdown();
	
	delete s_pxInputHandler;
	delete s_pxWindowPanel;
	delete s_pxTextureManager;

	SDL_GL_DeleteContext( s_xContext );
	SDL_DestroyWindow( s_pxWindow );
}


void Controller_Main::ChangeScreen ( const CONTROLLER_SCREEN eScreen )
{
	switch( s_eScreen )
	{
		case CONTROLLER_SCREEN_MAIN:	Controller_Screen_Main::Hide();		break;
		case CONTROLLER_SCREEN_EDITOR:	Controller_Screen_Editor::Hide();	break;
	}

	s_eScreen = eScreen;

	s_pxWindowPanel->DeleteChildren();

	switch( s_eScreen )
	{
		case CONTROLLER_SCREEN_MAIN:	Controller_Screen_Main::Show();		break;
		case CONTROLLER_SCREEN_EDITOR:	Controller_Screen_Editor::Show();	break;
	}
}

u_int Controller_Main::GetWindowID()
{
    return SDL_GetWindowID( s_pxWindow );
}

u_int Controller_Main::GetWidth()
{
    return s_uWidth;
}

u_int Controller_Main::GetHeight()
{
    return s_uHeight;
}

void Controller_Main::Resize( u_int uWidth, u_int uHeight )
{
    s_uWidth = uWidth;
    s_uHeight = uHeight;
}

bool Controller_Main::HandleEvent( const SDL_Event& xEvent )
{
	switch( xEvent.type )
	{
		case SDL_MOUSEMOTION:
		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
		case SDL_MOUSEWHEEL:
		case SDL_TEXTINPUT:
		case SDL_TEXTEDITING:
		case SDL_KEYDOWN:
		case SDL_KEYUP:
		{
			if(s_pxInputHandler) 
			{
				s_pxInputHandler->HandleEvent( xEvent );
				return true;
			}
		}
		break;

		case SDL_WINDOWEVENT:
		{
			switch( xEvent.window.event )
			{
				case SDL_WINDOWEVENT_RESIZED:
				{
					Resize( xEvent.window.data1, xEvent.window.data2 );
					return true;
				}
				case SDL_WINDOWEVENT_CLOSE:
				{
					Controller_ModalDialog::SetCallback( Quit_PostConfirmation );
					Controller_ModalDialog::Show( "Are your sure you want to quit?", DIALOGTYPE_YESNO );
					return true;
				}
			}
		}
		break;
	}

	return false;
}

void Controller_Main::AddModal( Widget* pxWidget )
{
	s_xModalStack.Push( pxWidget );
}

void Controller_Main::RemoveModal( Widget* pxWidget )
{
	// No point in enforcing removal from the top of the stack
	s_xModalStack.Delete( pxWidget );
}

void Controller_Main::Quit_PostConfirmation( Controller_ModalDialogResult eResult )
{
	if( eResult == DIALOGRESULT_YES )
	{
		Quit();
	}
}

//eof
